package com.atguigu.gmall.order.receiver;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.model.enums.PaymentStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.payment.client.PaymentFeignClient;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * @author Sanmier
 * @create 2020-12-21 8:42
 */
@Component
public class OrderReceiver {

    @Autowired
    private OrderService orderService;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private PaymentFeignClient paymentFeignClient;


    //监听取消订单
    @SneakyThrows
    @RabbitListener(queues = MqConst.QUEUE_ORDER_CANCEL)
    public void orderCancel(Long orderId, Message message, Channel channel){
        // System.out.println("取消订单业务。。。" + orderId);
        // 判断订单Id是否为空 ！
        // 这里不止要关闭电商平台的交易记录  还需要关闭支付宝的交易记录
        if (null!=orderId){
            // 为了防止重复消息这个消息。判断订单状态
            // 通过订单Id 来获取订单对象 select * from orderInfo where id = orderId
            OrderInfo orderInfo = orderService.getById(orderId);
            // 涉及到关闭orderInfo ,paymentInfo ,aliPay
            // 订单状态是未支付

            if (orderInfo!=null && "UNPAID".equals(orderInfo.getOrderStatus()) &&
                "UNPAID".equals(orderInfo.getProcessStatus())){
                // 关闭过期订单
                // orderService.execExpiredOrder(orderId);
                // 订单创建时就是未付款，判断是否有交易记录产生
                PaymentInfo paymentInfo = paymentFeignClient.getPaymentInfo(orderInfo.getOutTradeNo());

                if (paymentInfo!=null && paymentInfo.getPaymentStatus().equals(PaymentStatus.UNPAID.name())){
                    // 先查看是否有交易记录 {用户是否扫了二维码}
                    Boolean aBoolean = paymentFeignClient.checkPayment(orderId);

                    if (aBoolean){
                        // 有交易记录 ，关闭支付宝 防止用户在过期时间到的哪一个瞬间，付款
                        Boolean flag = paymentFeignClient.closePay(orderId);

                        if (flag){
                            // 用户未付款 ，开始关闭订单，关闭交易记录 2:表示要关闭交易记录paymentInfo 中有数据
                            orderService.execExpiredOrder(orderId,"2");
                        }else {
                            // 用户已经付款
                            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_PAYMENT_PAY, MqConst.ROUTING_PAYMENT_PAY, orderId);
                        }
                    }else {
                        // 在支付宝中没有交易记录，但是在电商中有交易记录
                        orderService.execExpiredOrder(orderId,"2");
                    }
                }else {
                    // 也就是说在paymentInfo 中根本没有交易记录。
                    orderService.execExpiredOrder(orderId,"1");
                }

            }
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }

    //监听支付是否成功
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.QUEUE_PAYMENT_PAY,durable = "true",autoDelete = "false"),
            exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_PAYMENT_PAY),
            key = {MqConst.ROUTING_PAYMENT_PAY}
    ))
    public void paySuccess(Long orderId, Message message, Channel channel){
        //判断orderId不为空
        if (orderId!=null){
            //理想的认为  orderId不为空  一定存在这个数据
            // update order_info  set order_status = ？， process_status=？where id=？
            // 药判断当前订单状态不能为close  或者是paid  在生成二维码之前判断了  此处可以省略
            orderService.updateOrderStatus(orderId,ProcessStatus.PAID);

            //订单发送消息给库存
            orderService.sendOrderStatus(orderId);
        }
    }

    //监听一个减库存结果的消息队列
    @SneakyThrows
    @RabbitListener(queues = MqConst.QUEUE_WARE_ORDER)
    public void updateOrderStatus(String msg,Message message,Channel channel){
        //判断获取的数据
        try {
            if (!StringUtils.isEmpty(msg)){
                //获取传递过来的数据  将其转化成map
                Map map = JSON.parseObject(msg, Map.class);
                String orderId = (String) map.get("orderId");
                String status = (String) map.get("status");
                //判断减库存的状态
                if ("DEDUCTED".equals(map.get("status"))){
                    //减库存成功
                    orderService.updateOrderStatus(Long.parseLong(orderId),ProcessStatus.WAITING_DELEVER);
                }else{
                    //减库存失败
                    orderService.updateOrderStatus(Long.parseLong(orderId), ProcessStatus.STOCK_EXCEPTION);
                    //通知管理员补货   等他找你  找客服小姐姐

                }
                //消息确认
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        } catch (NumberFormatException e) {
            //消息确认
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
